{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "\n",
    "[toc]\n",
    "\n",
    "## 更多变换矩阵\n",
    "\n",
    "### 矩阵在图形变换中的应用\n",
    "\n",
    "1. 让每个点的横坐标扩大a倍,纵坐标扩大b倍\n",
    "2. 让每个点关于X轴翻转\n",
    "3. 让每个点关于Y轴翻转\n",
    "4. 让每个店关于原点翻转\n",
    "5. 沿x方向错切\n",
    "6. 沿y方向错切\n",
    "\n",
    "### 01 让每个点的横坐标扩大a倍,纵坐标扩大b倍\n",
    "\n",
    "$\\begin{pmatrix} a &0 \\\\ 0&b  \\end{pmatrix}$\n",
    "\n",
    "### 02 让每个点关于X轴翻转\n",
    "\n",
    "$\\begin{pmatrix} 1 &0 \\\\ 0&-1  \\end{pmatrix}$\n",
    "\n",
    "\n",
    "### 03 让每个点关于Y轴翻转\n",
    "\n",
    "$\\begin{pmatrix} -1&0 \\\\ 0&1  \\end{pmatrix}$\n",
    "\n",
    "### 04 让每个店关于原点翻转\n",
    "\n",
    "$\\begin{pmatrix} -1&0 \\\\ 0&-1  \\end{pmatrix}$\n",
    "\n",
    "### 05 沿x方向错切\n",
    "\n",
    "$\\begin{pmatrix} 1&a \\\\ 0&1  \\end{pmatrix}$\n",
    "\n",
    "### 06 沿y方向错切\n",
    "\n",
    "$\\begin{pmatrix} 1&0 \\\\ a&1  \\end{pmatrix}$\n",
    "\n",
    "## 矩阵旋转变换与矩阵在图形学中的应用\n",
    "\n",
    "$T\\begin{pmatrix} x \\\\ y \\end{pmatrix} $=$\\begin{pmatrix} \\cos{\\theta}\\cdot{x} + \\sin{\\theta}\\cdot{y} \\\\ -\\sin{\\theta}\\cdot{x} + \\cos{\\theta}\\cdot{y} \\end{pmatrix}$\n",
    "\n",
    "T=$$\\begin{pmatrix} \\cos{\\theta} & \\sin{\\theta} \\\\ -\\sin{\\theta} & \\cos{\\theta}\\end{pmatrix}$\n",
    "\n",
    "```python\n",
    "import numpy as np\n",
    "import math\n",
    "\n",
    "from L04lesson.matrix import Matrix\n",
    "from L03lesson.vector import Vector\n",
    "\n",
    "import matplotlib\n",
    "\n",
    "matplotlib.use('TkAgg')\n",
    "import matplotlib.pyplot as mp\n",
    "\n",
    "if __name__ == '__main__':\n",
    "    points = [[0, 0], [0, 5], [3, 5], [3, 4], [1, 4], [1, 3], [2, 3], [2, 2], [1, 2], [1, 0]]\n",
    "\n",
    "    mp.figure('matrix transfor', figsize=(10, 10))\n",
    "    mp.xlim(-10, 10)\n",
    "    mp.ylim(-10, 10)\n",
    "    mp.plot([point[0] for point in points], [point[1] for point in points], label='origin')\n",
    "    # mp.axis('equal')\n",
    "    mp.rcParams['font.family'] = ['Source Han Sans CN']\n",
    "\n",
    "    P = Matrix(points)\n",
    "\n",
    "    # 缩放\n",
    "    T1 = Matrix([[2, 0], [0, 1.5]])\n",
    "    pt1 = P.dot(T1.T())\n",
    "    xpt1 = [p for p in pt1.col_vector(0)]\n",
    "    ypt1 = [p for p in pt1.col_vector(1)]\n",
    "    mp.plot(xpt1, ypt1, label='[2,1.5]')\n",
    "\n",
    "    # x轴翻转\n",
    "    T2 = Matrix([[1, 0], [0, -1]])\n",
    "    pt2 = P.dot(T2.T())\n",
    "    xpt2 = [p for p in pt2.col_vector(0)]\n",
    "    ypt2 = [p for p in pt2.col_vector(1)]\n",
    "    mp.plot(xpt2, ypt2, label=r'x轴翻转')\n",
    "\n",
    "    # 错切\n",
    "    # T3 = Matrix([[1, 0.5], [0, 1]])\n",
    "    # pt3 = P.dot(T3.T())\n",
    "    # xpt3 = [p for p in pt3.col_vector(0)]\n",
    "    # ypt3 = [p for p in pt3.col_vector(1)]\n",
    "    # mp.plot(xpt3, ypt3, label=r'x轴翻转')\n",
    "\n",
    "    # 旋转theta\n",
    "    theta = np.pi/4\n",
    "    T3 = Matrix([\n",
    "        [np.cos(theta), np.sin(theta)],\n",
    "        [-np.sin(theta), np.cos(theta)]\n",
    "    ])\n",
    "\n",
    "    print(T3)\n",
    "    pt3 = P.dot(T3.T())\n",
    "    xpt3 = [p for p in pt3.col_vector(0)]\n",
    "    ypt3 = [p for p in pt3.col_vector(1)]\n",
    "    mp.plot(xpt3, ypt3, label=r'rotate')\n",
    "\n",
    "    mp.legend()\n",
    "    mp.show()\n",
    "```\n",
    "\n",
    "## 单位矩阵\n",
    "\n",
    "$I_2=\\begin{pmatrix} 1 & 0 \\\\ 0 & 1 \\end{pmatrix}$\n",
    "\n",
    "- 主对角线都是1\n",
    "- 行=列,值为1\n",
    "- 方阵\n",
    "- $IA=AI=A$\n",
    "\n",
    "$I_2A=\\begin{pmatrix} 1 & 0 \\\\ 0 & 1 \\end{pmatrix}\\cdot\\begin{pmatrix} a & b& c \\\\ d& e& f \\end{pmatrix}=\\begin{pmatrix} a & b& c \\\\ d& e& f \\end{pmatrix}$\n",
    "\n",
    "$AI_3=\\begin{pmatrix} a & b& c \\\\ d& e& f \\end{pmatrix}\\cdot \\begin{pmatrix} 1 & 0& 0 \\\\ 0 & 1 & 0\\\\0& 0& 1\\end{pmatrix}=\\begin{pmatrix} a & b& c \\\\ d& e& f \\end{pmatrix}$\n",
    "\n",
    "## 单位矩阵实现\n",
    "\n",
    "```python\n",
    "def underlying_data(self):\n",
    "    return self._values\n",
    "\n",
    "@classmethod\n",
    "def identity(cls, n):\n",
    "    m = cls.zeros(n)\n",
    "    m = m.underlying_data()\n",
    "    for i in range(n):\n",
    "        m[i][i] = 1\n",
    "    return cls(m)\n",
    "```\n",
    "\n",
    "## 矩阵的逆\n",
    "\n",
    "1. 在矩阵中, AB=BA=I,则B是A的逆矩阵,记作 $B = A^{-1}$\n",
    "   1. A称为可逆矩阵,或非奇异(non-singular)矩阵(*不是所有矩阵都可逆*)\n",
    "   2. 有些矩阵是不可逆的! 称为不可逆矩阵,或奇异(singular)矩阵\n",
    "2. 如果有一个矩阵A既存在左逆矩阵B,又存在右矩阵C,则B=C\n",
    "   1. BA=I,则称B是A的左逆矩阵\n",
    "   2. AC=I,则称C是A的右逆矩阵\n",
    "3. 可逆矩阵一定是方阵,非方阵一定不可逆\n",
    "4. $A^0=I$\n",
    "\n",
    "## numpy使用单位矩阵,逆矩阵\n",
    "\n",
    "```python\n",
    "# 1. 生成单位矩阵\n",
    "In [8]: numpy.identity(3)\n",
    "Out[8]:\n",
    "array([[1., 0., 0.],\n",
    "       [0., 1., 0.],\n",
    "       [0., 0., 1.]])\n",
    "\n",
    "# 2. 生成逆矩阵\n",
    "## 2.1 矩阵A\n",
    "In [8]: numpy.identity(3)\n",
    "Out[8]:\n",
    "array([[1., 0., 0.],\n",
    "       [0., 1., 0.],\n",
    "       [0., 0., 1.]])\n",
    "## 2.2 A的逆矩阵\n",
    "In [12]: invA = numpy.linalg.inv(A)\n",
    "\n",
    "In [13]: invA\n",
    "Out[13]:\n",
    "array([[-4.50359963e+15,  9.00719925e+15, -4.50359963e+15],\n",
    "       [ 9.00719925e+15, -1.80143985e+16,  9.00719925e+15],\n",
    "       [-4.50359963e+15,  9.00719925e+15, -4.50359963e+15]])\n",
    "\n",
    "In [14]: A=numpy.array([1,2,3,4])\n",
    "\n",
    "In [15]: A.shape=(2,2)\n",
    "\n",
    "In [16]: A\n",
    "Out[16]:\n",
    "array([[1, 2],\n",
    "       [3, 4]])\n",
    "\n",
    "In [17]: B=numpy.linalg.inv(A)\n",
    "\n",
    "In [18]: B\n",
    "Out[18]:\n",
    "array([[-2. ,  1. ],\n",
    "       [ 1.5, -0.5]])\n",
    "\n",
    "In [20]: print(A.dot(B))\n",
    "[[1.00000000e+00 1.11022302e-16]\n",
    " [0.00000000e+00 1.00000000e+00]]\n",
    "\n",
    "In [21]: print(B.dot(A))\n",
    "[[1.0000000e+00 4.4408921e-16]\n",
    " [0.0000000e+00 1.0000000e+00]]\n",
    "```\n",
    "\n",
    "## 矩阵的逆的性质\n",
    "\n",
    "1. 逆矩阵唯一\n",
    "2. $(A^{-1})^{-1} = A$\n",
    "3. $(A \\cdot B)^{-1} = B^{-1}\\cdot A^{-1}$\n",
    "4. $(A \\cdot B)^{T} = B^{T}\\cdot A^{T}$\n",
    "5. $(A^T)^{-1} = (A^{-1})^T$\n",
    "\n",
    "## 看待矩阵的关键视角\n",
    "\n",
    "### 用矩阵表示空间\n",
    "\n",
    "1 行视角\n",
    "\n",
    "![72deba26149c3a1f42d3327d6734f80c.png](:/a4435ffaf4624382af8e05d8118941b4)\n",
    "\n",
    "2 列视角\n",
    "\n",
    "![d37f4007ddc4c17329fa2b49a4a288c9.png](:/f7d43e5e2a274a309838207d95be327e)\n",
    "![d024c89dff1d28820ad428910cf36779.png](:/ab3fcf3c1a2a4af89c0b90cb0dadebf2)\n",
    "\n",
    "3 矩阵空间\n",
    "\n",
    "![07c08fc72090e21e11abd0094ea6793c.png](:/0c3082d77977453cab9ff205d3aa660d)\n",
    "![ffb73cb20695c7e69d8a24164f2057bd.png](:/43cbd48cbc2f46b8bfaacc161ccb935f)"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.7.0"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
